package hsrt.vis;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.util.HashMap;

import javax.microedition.khronos.opengles.GL10;

import android.util.Log;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Bitmap.Config;

abstract class Sphere {
	
	protected static final int SPHERE_LATITUDES = 25; // L�nge
	protected static final int SPHERE_LONGITUDES = 55; // Breite
	public static final float PI = (float) Math.PI;
	public static final int INT_BYTES = 4;
	public static final int SHORT_BYTES = 2;
	
	private IntBuffer mVertexBuffer;
	protected IntBuffer mNormalBuffer;
	protected IntBuffer mColorBuffer;
	protected ShortBuffer mIndexBuffer;
	
	protected int dataCounter;
	protected Object dataHolder;
	
	public SphereData sd;
	public Bitmap mBitmap;
	public Bitmap mutableBitmap;
	public Config mConfig;
	public Canvas mCanvas;
	public Paint mPaint;
	
	/**
	 * SphereData, alle Daten ausgelagert aus der Create Funktion
	 * @author tlauria
	 *
	 */
	protected class SphereData {
		public int vidx = 0;
		public int nidx = 0;
		public int cidx = 0;
		public int iidx = 0;
		public int tris = 2 * (SPHERE_LATITUDES - 1) * (SPHERE_LONGITUDES - 1);
				
		public float radius = 1.5f;
		public float centerX = 0.0f;
		public float centerY = 0.5f;
		public float centerZ = 0.0f;
		public float minLongitude = 0.0f;
		public float maxLongitude = 360.0f;
		
		public int[] vertices 		= new int[3 * SPHERE_LATITUDES * SPHERE_LONGITUDES];
		public int[] colors 		= new int[3 * SPHERE_LATITUDES * SPHERE_LONGITUDES];
		public int[] normals 		= new int[3 * SPHERE_LATITUDES * SPHERE_LONGITUDES];
		
		public short[] indices        = new short[3 * tris];
	}
	
	/**
	 * Constructor 
	 * vor dem Create Aufruf können die SphereData Daten angepasst werden 
	 */	
	public Sphere() {
		this.sd = new SphereData();
	}	
	
	
	/**
	 * Create
	 * erzeugt Kugel
	 */
	final public void Create() {		
		prepare();
		prepareBuffer();
		return;
	}
	
	abstract protected void prepare();
	
	protected final void prepareBuffer () {
        ByteBuffer vbb = ByteBuffer.allocateDirect(sd.vertices.length * INT_BYTES);
        vbb.order(ByteOrder.nativeOrder());
        mVertexBuffer = vbb.asIntBuffer();
        mVertexBuffer.put(sd.vertices);
        mVertexBuffer.position(0);
        
        ByteBuffer nbb = ByteBuffer.allocateDirect(sd.normals.length * INT_BYTES);
        nbb.order(ByteOrder.nativeOrder());
        mNormalBuffer = nbb.asIntBuffer();
        mNormalBuffer.put(sd.normals);
        mNormalBuffer.position(0);
        
        ByteBuffer cbb = ByteBuffer.allocateDirect(sd.colors.length * INT_BYTES);
        cbb.order(ByteOrder.nativeOrder());
        mColorBuffer = cbb.asIntBuffer();
        mColorBuffer.put(sd.colors);
        mColorBuffer.position(0);
        
        ByteBuffer ibb = ByteBuffer.allocateDirect(sd.indices.length * SHORT_BYTES);
        ibb.order(ByteOrder.nativeOrder());
        mIndexBuffer = ibb.asShortBuffer();
        mIndexBuffer.put(sd.indices);
        mIndexBuffer.position(0);

        
/**************************************************************************************/
                 
        
	}
	
	public void draw(GL10 gl)
    {		
		gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
        gl.glColorPointer(3, GL10.GL_FIXED, 0, mColorBuffer);
        gl.glNormalPointer(GL10.GL_FIXED, 0, mNormalBuffer);
        
        
        //Textur
        /*gl.glEnable(GL10.GL_TEXTURE_2D);
        
	    mConfig = Config.ARGB_4444;
		mBitmap = Bitmap.createBitmap(10, 10, mConfig);
		//mBitmap = BitmapFactory.decodeResource(SphereView.getmContext().getResources(), R.drawable.gruen);
		mutableBitmap = mBitmap.copy(mConfig, true);
		mBitmap.recycle();
		
        mCanvas = new Canvas(mutableBitmap);
		mPaint = new Paint();
		mPaint.setStyle(Style.FILL);
		mPaint.setColor(Color.WHITE);
		mPaint.setTextSize(30);
		mCanvas.drawText("Hallo", 5, 5, mPaint);
		
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, mutableBitmap, 0);*/
				
        //Beleuchtung        
        gl.glEnable(GL10.GL_LIGHTING);
        gl.glEnable(GL10.GL_LIGHT0);
        gl.glEnable(GL10.GL_COLOR_MATERIAL);       
        
        
        gl.glEnable(GL10.GL_CULL_FACE);
        gl.glDrawElements(GL10.GL_TRIANGLES, mIndexBuffer.capacity(), GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
    }
	
	/**
     * Converts the given floating-point value to fixed-point.
     */
    public static int toFixed(float x) {
        return (int) (x * 65536.0);
    }
    
    /**
     * Returns the length of a vector, given as three floats.
     */
    public static float length(float vx, float vy, float vz) {
        return (float) Math.sqrt(vx * vx + vy * vy + vz * vz);
    }    
    public int getDataSize() {
		return this.dataCounter;
	}


}
